package discrete.math;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;

import javax.swing.JPanel;

public class GraphPanel extends JPanel {

	private static final long serialVersionUID = -6622390153400108744L;
	private MatrixMath matrix;
	private int numVertices;
	private int maxHeight = 400;
	private int maxWidth = 500;
	private int xChange = 25;
	private int yChange = 25;
	private Point startPoint = new Point(250, 25);
	private ArrayList<Point> vertices = new ArrayList<Point>();
	private boolean drawn = false;
	
	public GraphPanel(MatrixMath matrix) {
		setBackground(Color.white);
		this.matrix = matrix;
		this.numVertices = matrix.getMrows() - 1;
		this.vertices.add(startPoint);
	}
	
	public GraphPanel(boolean doubleBuffered, MatrixMath matrix) {
		this(matrix);
		this.setDoubleBuffered(doubleBuffered);
	}
	
	public void paintComponent(Graphics g) {		
		// Paint background
		super.paintComponent(g);

		// Set current drawing color
		g.setColor (Color.BLACK);
		   
		findVertices();
		if(vertices.size() > 0) {
			vertices.remove(vertices.size() - 1);
			char label = 'A';
			int count = 0;
			for(Point p : vertices) {
				g.fillOval((int)p.getX(), (int)p.getY(), 3, 3);
				if(!drawn) {
					g.drawString(String.valueOf(label), (int)p.getX(), ((int)p.getY() - 5));
				}
				label += 1;
				++count;
				if(count == numVertices) {
					drawn = true;
				}
			}			
			matrix.printMatrix();
			for(int i = 0; i < numVertices; ++i) {
				for(int j = 0; j < numVertices; ++j) {
					if(matrix.printSingleValue(i, j) == 1) {
						Point startPoint = vertices.get(i - 1);
						Point endPoint = vertices.get(j - 1);
						g.drawLine((int)startPoint.getX() + 1, (int)startPoint.getY() + 1, (int)endPoint.getX() + 1, (int)endPoint.getY() + 1);
					}
				}
			}
		}
	}	

	private void findVertices() {
		Point nextPoint;
		Point prevPoint = startPoint;		
		
		if ((numVertices % 5) == 0) {
			for (int i = 0; i < (numVertices / 5); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = (numVertices / 5); i < ((numVertices / 5) * 2); ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = ((numVertices / 5) * 2); i < ((numVertices / 5) * 3); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2)), (int)prevPoint.getY());
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = ((numVertices / 5) * 3); i < ((numVertices / 5) * 4); ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() - (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = ((numVertices / 5) * 4); i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if ((numVertices % 4) == 0) {
			for (int i = 0; i < (numVertices / 4); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = (numVertices / 4); i < (numVertices / 2); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = (numVertices / 2); i < ((numVertices / 4) * 3); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = ((numVertices / 4) * 3); i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if ((numVertices % 3) == 0) {
			for (int i = 0; i < (numVertices / 3); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = (numVertices / 3); i < ((numVertices / 3) * 2); ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2)), (int)prevPoint.getY());
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = ((numVertices / 3) * 2); i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}			
		} else if (numVertices == 2) {
			nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 3)));
			vertices.add(nextPoint);
		} else if (numVertices == 7) {
			for (int i = 0; i < 2; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 2)));
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 4)), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() - (yChange * 2)));
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			for (int i = 5; i < 7; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if (numVertices == 11) {
			for (int i = 0; i < 4; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 17), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 16), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 17), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			for (int i = 7; i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}			
		} else if (numVertices == 13) {
			for (int i = 0; i < 2; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 2; i < 5; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			nextPoint = new Point((int)(prevPoint.getX() + (xChange + 8)), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange + 9)), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange + 8)), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			for (int i = 8; i < 11; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() - (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 11; i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if (numVertices == 14) {
			for (int i = 0; i < 5; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 12), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 13), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 13), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 12), (int)prevPoint.getY());
			vertices.add(nextPoint);
			prevPoint = nextPoint;
			for (int i = 9; i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if (numVertices == 17) {
			for (int i = 0; i < 4; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 4; i < 7; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 7; i < 10; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 21), (int)prevPoint.getY());
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 10; i < 13; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() - (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 13; i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		} else if (numVertices == 19) {
			for (int i = 0; i < 4; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() + yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 4; i < 8; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() + (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 8; i < 11; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() + (xChange * 2) + 17), (int)prevPoint.getY());
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 11; i < 15; ++i) {
				nextPoint = new Point((int)prevPoint.getX(), (int)(prevPoint.getY() - (yChange * 2)));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
			for (int i = 15; i < numVertices; ++i) {
				nextPoint = new Point((int)(prevPoint.getX() - xChange), (int)(prevPoint.getY() - yChange));
				vertices.add(nextPoint);
				prevPoint = nextPoint;
			}
		}
		
	}

	public void clear() {
		Graphics g = this.getGraphics();
		g.clearRect(0, 0, maxWidth, maxHeight);
		drawn = false;
	}
}
